package com.cndw.kungfu.domain;

import com.cndw.kungfu.config.Constants;
import com.cndw.kungfu.config.ConstantsIntKey;
import com.cndw.kungfu.config.ConstantsModel;
import com.cndw.kungfu.event.once.PlayerUpgradeTask;
import com.cndw.kungfu.event.once.SystemCloudAlarm;
import com.cndw.kungfu.ext.NumberProcesser;
import com.cndw.kungfu.ext.TimeProcesser;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.battle.Fighter;
import com.cndw.kungfu.model.battle.FighterPlayer;
import com.cndw.kungfu.model.battle.Team;
import com.cndw.kungfu.model.goods.PlayerBoxs;
import com.cndw.kungfu.model.goods.addition.Addition;
import com.cndw.kungfu.model.goods.addition.AdditionMain;
import com.cndw.kungfu.model.player.PlayerDataInfo;
import com.cndw.kungfu.vo.PlayerVO;
import com.cndw.kungfu.vo.ScenePlayerVO;
import com.cndw.kungfu.vo.battlevo.TeamPlayerVO;
import com.cndw.rpg.framework.SessionHolder;

/**
 * 玩家对象实体类
 * 
 * @author fantadust
 * @date 2011-4-29 下午04:57:52
 */
public class Player extends PlayerBase {
	/**
	 * 我的线路
	 */
	private int subLine;
	/**
	 * 临时信息
	 */
	private transient int tx;
	private transient int ty;
	private transient int ts;
	private transient long tz;
	/**
	 * 上次加载数据时间
	 */
	private int lastRead = 0;
	private int lastPlan = 0;

	/**
	 * 状态 0 无.1 战斗 2.决斗 4刺杀 8携带火药包
	 */
	private int state;
	/**
	 * 玩家队伍id
	 */
	private int teamId;

	/**
	 * 背包
	 */
	private PlayerBoxs playerBoxs;
	/**
	 * 临时数组集合
	 */
	private PlayerDataInfo playerDataInfo;
	/**
	 * 玩家对应的唯一战斗角色
	 */
	private Fighter linkedFighter;

	/**
	 * 设置等级
	 * 
	 * @param alter
	 */
	public synchronized void alterLevel(int alter) {
		int newLevel = NumberProcesser.between(alter + getLevel(), 0, Constants.playerMaxLevel);
		setLevel(newLevel);

	}

	/**
	 * 设置经验
	 * 
	 * @param alter
	 */
	public synchronized void alterExp(int alter) {
		if (alter == 0) {
			return;
		}
		if (alter > 0) {
			int oAdd = NumberProcesser.percentOnlyAddValue(alter, 30);
			if (level >= 15) {
				alterExpPool(oAdd);
			}
			if (getDataInfo().getPetId() > 0 && getDataInfo().getPet() != null && getDataInfo().getPet().getLevel() < level) {
				getDataInfo().getPet().alterExp(oAdd);
			}
		}
		long newExp = alter + getExp();
		setExp(newExp);
		if (alter > 0) {
			autoUpLevel();// 检测是否升级
		}
	}

	/**
	 * 修改经验池的经验
	 * 
	 * @param alter
	 */
	public synchronized void alterExpPool(long alter) {
		if (alter == 0) {
			return;
		}
		// else if (alter > 0 && expPool > Integer.MAX_VALUE - alter) {
		// return;
		// }
		expPool += alter;
	}

	public synchronized void alterExpJar(int alter) {
		if (alter == 0) {
			return;
		}
		expJar += alter;
	}

	/**
	 * 设置血量
	 * 
	 * @param alter
	 */
	public synchronized void alterHp(int alter) {
		int newHp = NumberProcesser.between(alter + getHp(), 0, getMaxHp());
		setHp(newHp);
	}

	/**
	 * 设置魔法量
	 * 
	 * @param alter
	 */
	public synchronized void alterMp(int alter) {
		int newMp = NumberProcesser.between(alter + getMp(), 0, getMaxMp());
		setMp(newMp);
	}

	/**
	 * 设置财富
	 * 
	 * @param alter
	 */
	public synchronized void alterAsset(int alter) {
		asset = asset + alter;
	}

	public int getGoldAll() {
		return gold + goldBing;
	}

	/**
	 * 优先扣除绑定金币,再扣除金币
	 * 
	 * @param alter
	 */
	public synchronized void alterGoldAll(int alter) {
		goldBing = goldBing + alter;
		if (goldBing < 0) {
			gold = gold + goldBing;
			goldBing = 0 ;
		}
		if (alter > 0 || gold < 0) {
			new Throwable("id:" + playerId + " alter:" + alter).printStackTrace();
			SystemCloudAlarm.send(playerId + " | " + alter, SystemCloudAlarm.some_e);
		}
	}

	/**
	 * 只扣除金币
	 * 
	 * @param alter
	 */
	public synchronized void alterGold(int alter) {
		gold = gold + alter;
		if (alter > 0 || gold < 0) {
			new Throwable("id:" + playerId + " alter:" + alter).printStackTrace();
			SystemCloudAlarm.send(playerId + " | " + alter, SystemCloudAlarm.some_e);
		}
	}

	public synchronized void receiveGold(int alter) {
		gold = gold + alter;
	}

	public synchronized void receiveGoldBind(int alter) {
		goldBing = goldBing + alter;
	}

	public synchronized void alterGoldTicke(int alter) {
		goldTicke = goldTicke + alter;
	}

	public synchronized void alterVipScore(int alter) {
		vipScore = vipScore + alter;
	}

	/**
	 * 设置4项属性
	 * 
	 * @param alter
	 */
	public synchronized void alterPower(int alter) {
		power = power + alter;
	}

	public synchronized void alterPhysical(int alter) {
		physical = physical + alter;
	}

	public synchronized void alterAgile(int alter) {
		agile = agile + alter;
	}

	public synchronized void alterWit(int alter) {
		wit = wit + alter;
	}

	public synchronized void alterBloodBag(int alter) {
		int tmpBag = NumberProcesser.between(bloodBag + alter, 0, ConstantsModel.bloodBagMax);
		setBloodBag(tmpBag);

	}

	public synchronized void alterMagicBag(int alter) {
		int tmpBag = NumberProcesser.between(magicBag + alter, 0, ConstantsModel.bloodBagMax);
		setMagicBag(tmpBag);
	}

	/**
	 * 使用血包
	 */
	public synchronized void useBloodMagicBag() {
		if (level <= 10) {
			hp = maxHp;
			mp = maxMp;
			return;
		}
		int tmpBlood = NumberProcesser.between(maxHp - hp, 0, bloodBag);
		int tmpMagic = NumberProcesser.between(maxMp - mp, 0, magicBag);
		if (tmpBlood > 0) {
			alterBloodBag(-tmpBlood);
			alterHp(tmpBlood);
		}
		if (tmpMagic > 0) {
			alterMagicBag(-tmpMagic);
			alterMp(tmpMagic);
		}
		hp = hp == 0 ? 1 : hp;
		mp = mp == 0 ? 1 : mp;
	}

	public void useBloodMagicBagAndPet() {
		useBloodMagicBag();
		if (getDataInfo().intDataGet(ConstantsIntKey.aPetBag) == 1 && getDataInfo().getPet() != null) {
			getDataInfo().getPet().useBloodMagicBag();
		}
	}

	public void fullBloodMagic() {
		hp = maxHp;
		mp = maxMp;
	}

	public void fullBloodMagicPet() {
		if (getDataInfo().getPet() != null) {
			getDataInfo().getPet().fullHpMp();
		}
	}

	public int[] blodMagicMemory() {
		int[] olds = new int[4];
		olds[0] = hp;
		olds[1] = mp;
		if (getDataInfo().getPet() != null) {
			olds[2] = getDataInfo().getPet().getHp();
			olds[3] = getDataInfo().getPet().getMp();
			getDataInfo().getPet().fullHpMp();
		}
		hp = maxHp;
		mp = maxMp;
		return olds;
	}

	public void blodMagicMemoryRevert(int[] olds) {
		if (olds != null && olds.length == 4) {
			hp = olds[0];
			mp = olds[1];
			if (getDataInfo().getPet() != null) {
				getDataInfo().getPet().setHp(olds[2]);
				getDataInfo().getPet().setMp(olds[3]);
			}
		}
	}

	/**
	 * 行走有关
	 * 
	 * @return
	 */

	public int getTx() {
		return tx;
	}

	public int getTs() {
		return ts;
	}

	public void setTs(int ts) {
		this.ts = ts;
	}

	public void setTx(int tx) {
		this.tx = tx;
	}

	public int getTy() {
		return ty;
	}

	public void setTy(int ty) {
		this.ty = ty;
	}

	public long getTz() {
		return tz;
	}

	public void setTz(long tz) {
		this.tz = tz;
	}

	public int getSubLine() {
		return subLine;
	}

	public void setSubLine(int subLine) {
		this.subLine = subLine;
	}

	public boolean isOnline() {
		return SessionHolder.getInstance().isOnline(playerId);
	}

	public int getState() {
		return state;
	}

	public boolean stateContains(int state) {
		return (this.state & state) > 0;
	}

	public void stateAdd(int type) {
		state = state | type;
	}

	public void stateRemove(int type) {
		state = state & ~type;
	}

	public int getLastRead() {
		return lastRead;
	}

	public void setLastRead(int lastRead) {
		this.lastRead = lastRead;
	}

	public int getLastPlan() {
		return lastPlan;
	}

	public void setLastPlan(int lastPlan) {
		this.lastPlan = lastPlan;
	}

	public int getTeamId() {
		return teamId;
	}

	public void setTeamId(int teamId) {
		this.teamId = teamId;
	}

	public Team getTeam() {
		if (teamId > 0) {
			return Context.getDataServer().getTeam(teamId);
		}
		return null;
	}

	/**
	 * 下一级别需要的经验
	 * 
	 * @return
	 */
	public long getExpNeed() {
		LevelUpgrade levelUpgrade = LevelUpgrade.getByLevel(level);

		return levelUpgrade.getPlayerExp();

	}

	public PlayerBoxs getPlayerBoxs() {
		if (playerBoxs == null) {
			synchronized (this) {
				if (playerBoxs == null) {
					playerBoxs = Context.getGoodsServer().initBoxsFromDb(playerId, boxsGirds, holdGrids);
				}
			}
		}
		return playerBoxs;
	}

	public PlayerDataInfo getDataInfo() {
		if (playerDataInfo == null) {
			synchronized (this) {
				if (playerDataInfo == null) {
					playerDataInfo = Context.getPlayerServer().getDataInfoDB(playerId);
				}
			}
		}
		return playerDataInfo;
	}

	public boolean isInitDataInfo() {
		return playerDataInfo != null;
	}

	public Fighter getLikedFighter() {
		if (linkedFighter == null) {
			synchronized (this) {
				if (linkedFighter == null) {
					linkedFighter = new FighterPlayer(this);
				}
			}

		}
		return linkedFighter;
	}

	public Fighter getLikedFighter(int conff) {
		if (conff == 0) {
			return getLikedFighter();
		}
		return new FighterPlayer(this, conff);
	}

	public Fighter getLikedFighterPet(int conff) {
		if (getDataInfo().getPet() != null) {
			return getDataInfo().getPet().getLikedFighter(conff);
		}
		return null;
	}

	/**
	 * 我的可分配点数
	 * 
	 * @return
	 */
	public int getFreePoint() {
		return 0;
	}

	public synchronized void autoUpLevel() {
		boolean isChange = false;
		while (level < Constants.playerMaxLevel && exp >= getExpNeed()) {
			isChange = true;
			exp -= getExpNeed();
			alterLevel(1);// 提高到目标等级

			if (level >= 2) {
				Vocation vocation = Context.getCongfigServer().getVocation(vocationId);
				alterPower(vocation.getAddPower());
				alterPhysical(vocation.getAddPhysical());
				alterAgile(vocation.getAddAgile());
				alterWit(vocation.getAddWit());
			}

		}
		if (isChange) {
			Context.getPlayerServer().clacProperties(this);
			setHp(maxHp);
			setMp(maxMp);
			// 执行更新其他事情 改变属性 进行广播
			Runnable r = new PlayerUpgradeTask(this, level);
			Context.getTimerServer().scheduleMilliSeconds(r, 1000);
		}

	}

	public Addition getKnight() {
		return AdditionMain.getKnight(getKnightTrueLevel());
	}

	public int getKnightTrueLevel() {
		if (knightLevel <= 0 || knightExpired < TimeProcesser.getUnixTime()) {
			return 0;
		}
		return knightLevel;
	}

	/**
	 * 设置离线时间和结算在线时间
	 */
	public void updateOffLineAndOnlineTime() {
		offLineTime = TimeProcesser.getUnixTime();
		onLineTime += offLineTime - lastLogin;
		// 把在线时间记录进去
		getDataInfo().getEveryDay().setOnLine(getTodayOnLine());
	}

	public int getTodayOnLine() {
		int morningTime = TimeProcesser.getMorningTime();
		int beginTime = lastLogin <= morningTime ? morningTime : lastLogin;
		return TimeProcesser.getUnixTime() - beginTime + getDataInfo().getEveryDay().getOnLine();
	}

	@Deprecated
	public void setTodayOnLine(int todayOnLine) {

	}

	public int getDescipleMax() {
		return LevelUpgrade.getByLevel(level).getDiscipleMax();
	}

	public int getCampNum() {
		return LevelUpgrade.getByLevel(level).getCampMax();
	}

	@Override
	public boolean syncDB() {
		return Context.getSyncServer().syncDB(this);
	}

	public void clacProperties() {
		Context.getPlayerServer().clacProperties(this);
	}

	/**
	 * 扩展函数
	 * 
	 * @return
	 */
	public PlayerVO toPlayerVO() {
		return new PlayerVO(this);
	}

	public PlayerVO toOtherPlayerVO() {
		return new PlayerVO(this, true);
	}

	public ScenePlayerVO toScenePlayerVO() {
		return new ScenePlayerVO(this);
	}

	public TeamPlayerVO toTeamPlayerVO() {
		return new TeamPlayerVO(this);
	}

}
